/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 - 2008 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.web.gwt.form.client.widget.item.impl;

import com.genia.toolbox.web.gwt.basics.client.GwtHelper;
import com.genia.toolbox.web.gwt.basics.client.oracle.SelectSuggestBox;
import com.genia.toolbox.web.gwt.basics.client.widget.HyperLinkButton;
import com.genia.toolbox.web.gwt.basics.client.widget.WidgetFactory;
import com.genia.toolbox.web.gwt.form.client.CssNames;
import com.genia.toolbox.web.gwt.form.client.form.SubFormSimpleItem;
import com.genia.toolbox.web.gwt.form.client.manager.FormManager;
import com.genia.toolbox.web.gwt.form.client.message.Messages;
import com.genia.toolbox.web.gwt.form.client.oracle.FormServiceSuggestOracle;
import com.genia.toolbox.web.gwt.form.client.widget.item.ItemWidget;
import com.genia.toolbox.web.gwt.form.client.widget.item.ItemWidgetModifyListener;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

/**
 * This class is the widget representing a {@link SubFormSimpleItem}.
 */
public class SubFormSimpleItemWidget
    extends AbstractSimpleValuedItemWidget<SubFormSimpleItem>
{

  /**
   * the Panel containing all the sub-widgets.
   */
  private final transient HorizontalPanel hPanel = new HorizontalPanel();

  /**
   * the textbox allowing the user to type.
   */
  private final transient SelectSuggestBox suggestBox;

  /**
   * {@link TextBox} to display when the item is disabled.
   */
  private final transient TextBox disabledTextBox;

  /**
   * the widgets that the setErrorMessage must modify.
   */
  private final transient Widget[] widgetsToToggle;

  /**
   * the oracle to use.
   */
  private final FormServiceSuggestOracle oracle;

  /**
   * the current value of the object. Only used if the widget is disabled.
   */
  private String value = null;



  /**
   * constructor.
   * 
   * @param formManager
   *          the manager handling the current form
   * @param item
   *          the item begin rendered
   */
  public SubFormSimpleItemWidget(final FormManager formManager, final SubFormSimpleItem item)
  {
    super(item);

    // get widgets.
    final Label label = new Label();

    // set the i18nMessage to the label.
    GwtHelper.fillText(label, item.getLabelKey());

    hPanel.addStyleName(CssNames.SUB_FORM_SIMPLE_ITEM_CSS_STYLE);
    hPanel.addStyleName(item.getName());

    hPanel.add(label);

    oracle = new FormServiceSuggestOracle();
    oracle.setFieldName(item.getName());
    oracle.setFormIdentifier(formManager.getFormIdentifier());
    oracle.setDataIdentifier(formManager.getDataIdentifier());
    oracle.setDisplayStringHTML(item.isDisplayStringHTML());

    if (item.isEnabled()) {
      suggestBox = new SelectSuggestBox(oracle);
      disabledTextBox = null;
      widgetsToToggle = new Widget[] { hPanel, suggestBox };
      hPanel.add(suggestBox);
      if (item.getSubFormPolicy().isCanCreate() || item.getSubFormPolicy().isShowDisabled()) {
        final HyperLinkButton newButton = WidgetFactory.newHyperLinkButton(Messages.NEW_BUTTON_MESSAGE, CssNames.NEW_BUTTON_CSS_STYLE);
        newButton.setEnabled(item.getSubFormPolicy().isCanCreate());
        if (item.getSubFormPolicy().isCanCreate()) {
          newButton.addClickListener(new ClickListener()
          {

            public void onClick(final Widget widget)
            {
              SubFormHelper.startNewForm(SubFormSimpleItemWidget.this, formManager, null, false);
            }

          });
        }
        hPanel.add(newButton);
      }

      if (item.getSubFormPolicy().isCanUpdate() || item.getSubFormPolicy().isShowDisabled()) {
        final HyperLinkButton updateButton = WidgetFactory.newHyperLinkButton(Messages.UPDATE_BUTTON_MESSAGE, CssNames.UPDATE_BUTTON_CSS_STYLE);
        updateButton.setEnabled(item.getSubFormPolicy().isCanCreate());
        updateButton.setVisible(false);
        if (item.getSubFormPolicy().isCanCreate()) {
          updateButton.addClickListener(new ClickListener()
          {

            public void onClick(final Widget widget)
            {
              SubFormHelper.startNewForm(SubFormSimpleItemWidget.this, formManager, formManager.getValue(item.getName()), false);
            }

          });
        }
        addModifyListener(new ItemWidgetModifyListener()
        {

          public void onModify(final ItemWidget item)
          {
            final SubFormSimpleItemWidget realItem = (SubFormSimpleItemWidget) item;
            updateButton.setVisible(realItem.getValue() != null);
          }
        });
        hPanel.add(updateButton);
      }
    }
    else {
      suggestBox = null;
      disabledTextBox = new TextBox();
      disabledTextBox.setEnabled(false);
      widgetsToToggle = new Widget[] { hPanel, disabledTextBox };
      hPanel.add(disabledTextBox);
    }

    initWidget(hPanel);
  }



  /**
   * returns an array containing all the widgets that the setErrorMessage must
   * modify.
   * 
   * @return an array containing all the widgets that the setErrorMessage must
   *         modify
   */
  @Override
  protected Widget[] getWidgetsToToggle()
  {
    return widgetsToToggle;
  }



  /**
   * add a listener that is called each time the value of this object change.
   * 
   * @param modifyListener
   *          the callback
   */
  public void addModifyListener(final ItemWidgetModifyListener modifyListener)
  {
    if (getItem().isEnabled()) {
      suggestBox.addChangeListener(new ChangeListener()
      {
        public void onChange(final Widget widget)
        {
          modifyListener.onModify(SubFormSimpleItemWidget.this);
        }
      });
    }
  }



  /**
   * returns the current value of this item.
   * 
   * @return a <code>String</code> representing the current values of this item
   */
  @Override
  public String getValue()
  {
    if (getItem().isEnabled()) {
      return suggestBox.getValue();
    }
    else {
      return value;
    }
  }



  /**
   * set the current value of this item.
   * 
   * @param value
   *          a <code>String</code> representing the new values of this item
   */
  @Override
  public void setValue(final String value)
  {
    if (getItem().isEnabled()) {
      suggestBox.setValue(value);
    }
    else {
      this.value = value;
      oracle.requestText(value, disabledTextBox);
    }
  }
}
